<template>
  <div v-show="isShow" @click="goBack" class="backtop">
    <svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16">
      <path d="M825.568 555.328l-287.392-289.28C531.808 259.648 523.488 256.576 515.2 256.64 514.08 256.544 513.12 256 512 256c-4.672 0-9.024 1.088-13.024 2.88-4.032 1.536-7.872 3.872-11.136 7.136l-259.328 258.88c-12.512 12.48-12.544 32.736-0.032 45.248 6.24 6.272 14.432 9.408 22.656 9.408 8.192 0 16.352-3.136 22.624-9.344L480 364.288 480 928c0 17.696 14.336 32 32 32s32-14.304 32-32L544 362.72l236.192 237.728c6.24 6.272 14.496 9.44 22.688 9.44s16.32-3.104 22.56-9.312C838.016 588.128 838.048 567.84 825.568 555.328zM864 192 160 192C142.336 192 128 177.664 128 160s14.336-32 32-32l704 0c17.696 0 32 14.336 32 32S881.696 192 864 192z"></path>
    </svg>
  </div>
</template>

<script>
export default {
  data() {
    return {
      scrollEl: null,
      scrollTop: 0, // 默认距离顶部的距离
      appearTop: 106, // 显示距离顶部的距离
      isShow: false, // 控制返回顶部按钮的显隐
      scrollTrigger: false // 默认初始值
    }
  },

  mounted () {
    let scrollEl = document.documentElement
    this.scrollEl = scrollEl
    document.addEventListener('scroll', (e) => {
      this.handleScrollTop(e)
    })
    this.handleScrollTop()
  },

  methods: {
    // 返回顶部事件
    goBack() {
      // 防止频繁点击，故返回顶部后设置scrollTrigger为初始值
      if (this.scrollTrigger) {
        return
      }
      // 获取当前距离顶部的距离
      let scrollTop = this.scrollTop
      let steep = scrollTop / 2000
      let timer = setInterval(() => {
        this.scrollTrigger = true
        // 滚动的速度逐渐变快，第一次走2000/1，然后减去已走的距离，下一次用剩下的距离再减去步进值，步进值也是不断变化，这样速度会越来越快
        scrollTop -= steep
        // 步进值不改变的话会匀速缓慢上滑，不断增加步进值上滑的距离增加，视觉效果速度变快
        steep += 20
        if (scrollTop <= 0) {
          clearInterval(timer)
          this.scrollTrigger = false
        }
        this.scrollEl.scrollTop = scrollTop
      }, 30)
    },
    // 监听滚动条
    handleScrollTop(e) {
      // 设备一屏的高度
      let clientHeight =
        document.documentElement.clientHeight || document.body.clientHeight
      let scrollTop = this.scrollEl.scrollTop
      this.scrollTop = scrollTop
      // 判断距离顶部多少显示回到顶部图标
      if (scrollTop && this.scrollTop > this.appearTop) {
        this.isShow = true
      } else if (scrollTop > clientHeight) {
        this.isShow = true
      } else {
        this.isShow = false
      }
    }
  }
}
</script>

<style lang="less">
.backtop {
  position: fixed;
  z-index: 90;
  bottom: 8px;
  right: 8px;
  box-sizing: border-box;
  text-align: center;
  cursor: pointer;
  width: 36px;
  height: 36px;
  line-height: 36px;
  background: #007bff;
  overflow: hidden;
  border-radius: 50%;
  // display: none;
  opacity: 0.7;
  transition-duration: 0.3s;
  &:hover {
    opacity: 1;
  }
  svg {
    width: 20px;
    height: 20px;
    display: inline-block;
    fill: #fff;
    vertical-align: middle;
    margin: -3px 0 0;
  }
}
</style>